
#include "kb.h"                 // keybaord event type 
#include "touch_algorithm.h"    // touch event type 
#include "custom_event.h"
#include "gui.h"                // GUI header

#include "views.h"              // include all views 
#include "log.h"                // LOG file 
#define LOG     LOG_INFO0


#include "xapp_clock.h"
#include "xapp_exercise.h"
#include "xapp_localize.h"


enum tagExerciseSelectItem
{
    tagExerciseSelectItemRunning,
    tagExerciseSelectItemWalking,
    tagExerciseSelectItemRiding,
    tagExerciseSelectItemClimbing,
    tagExerciseSelectItemSwimming,
    tagExerciseSelectItemRopeskipping,
    tagExerciseSelectItemHula,
    tagExerciseSelectItemBasketball,
    tagExerciseSelectItemVolleyball,
    tagExerciseSelectItemPingpong,
    tagExerciseSelectItemBadmiton,
    tagExerciseSelectItemFootball,
    tagExerciseSelectItemCount,

    tagExerciseSelectReturn,
};




typedef struct
{
    uint8_t type;   // exercise type 
    uint8_t idx;    // index of icon
    uint16_t text;  // text tag 
}item_t;

const static item_t item_list[] = 
{
    // RUNNING
    { TASK_EXERCISE_TYPE_RUNNING,         0,        TEXT_TAG_EXERCISE_RUNNING },
    // WALKING-RACE
    { TASK_EXERCISE_TYPE_WALKINGRACE,     1,        TEXT_TAG_EXERCISE_WALKING_RACE },
    // Riding
    { TASK_EXERCISE_TYPE_RIDING,          4,        TEXT_TAG_EXERCISE_RIDING },
    // Climbing
    { TASK_EXERCISE_TYPE_CLIMBING,        5,        TEXT_TAG_EXERCISE_CLIMBING },
    // Swimming
    { TASK_EXERCISE_TYPE_SWIMMING,        6,        TEXT_TAG_EXERCISE_SWIMMING },
    // Ropeskipping
    { TASK_EXERCISE_TYPE_ROPESKIPPING,    7,        TEXT_TAG_EXERCISE_ROPESKIPPING },
    // Hula
    { TASK_EXERCISE_TYPE_HULA,            8,        TEXT_TAG_EXERCISE_HULA },
    // Baseketball
    { TASK_EXERCISE_TYPE_BASKETBALL,      9,        TEXT_TAG_EXERCISE_BAKSET_BALL },
    // Volleyball 
    { TASK_EXERCISE_TYPE_VOLLEYBALL,      10,        TEXT_TAG_EXERCISE_VOLLEY_BALL },
    // Pingpong
    { TASK_EXERCISE_TYPE_PINGPONG,        11,        TEXT_TAG_EXERCISE_PINGPONG },
    // Badminton
    { TASK_EXERCISE_TYPE_BADMINTON,        12,        TEXT_TAG_EXERCISE_BAMINTON },
    // Football
    { TASK_EXERCISE_TYPE_FOOTBALL,        13,        TEXT_TAG_EXERCISE_FOOTBALL },
};


#define ItemCount   6 

#define ITEM_HEIGHT         90
#define ITEM_IN_VIEWS       (GUI_LCD_RES_V / ITEM_HEIGHT)
#define ROLL_V_MAX_OFFSET     (1 * ITEM_HEIGHT)
#define ROLL_V_MIN_OFFSET     (-(ITEM_HEIGHT * (tagExerciseSelectItemCount - ITEM_IN_VIEWS + 1)))
#define ROLL_TOTAL_OFFSET       (ROLL_V_MAX_OFFSET - ROLL_V_MIN_OFFSET)

#define IDX_MINIMUM         (-1)
#define IDX_MAXIMUM         (tagExerciseSelectItemCount)

// declare function 
GUI_VIEW_FUNC_DECLARE_ALL;
static void local_view_event_handler( uint32_t tag );
static void list_item_handler(uint32_t tag);

const static ui_widgets_type_t wglExerciseSelection/*1. modify name*/[] = 
{
    // set background black 
    [0] = uiCanvas(0, 0, GUI_LCD_RES_H, GUI_LCD_RES_V, COLOR_BLACK ),

    //progress bar 
    [1] = uiCanvas( 0, ITEM_HEIGHT * 1, GUI_LCD_RES_H, ITEM_HEIGHT, COLOR_GRAY2 ), // 用于按下位置
    // 
    [2] = uiStackTouch( 0, ITEM_HEIGHT * (-1), GUI_LCD_RES_H, ITEM_HEIGHT, 2, 0 ),
    [3] = uiDigital( IMG_Exercise_Type_Icon_075_075_14, SIZE_SCALE(14), (ITEM_HEIGHT-SIZE_SCALE(50))/2, SIZE_SCALE(50), SIZE_SCALE(50) ),
    [4] = uiTextScroll( SIZE_SCALE(70), 0, GUI_LCD_RES_H - SIZE_SCALE(70),  ITEM_HEIGHT, COLOR_BLACK, COLOR_WHITE, ALIGN_LEFT_CENTOR, FILL_NONE, ENCODING_UNICODE, FONT_UNICODE_20_29),

    // 
    [5] = uiStackTouch( 0, ITEM_HEIGHT * 0, GUI_LCD_RES_H, ITEM_HEIGHT, 2, 1 ),
    [6] = uiDigital( IMG_Exercise_Type_Icon_075_075_14, SIZE_SCALE(14), (ITEM_HEIGHT-SIZE_SCALE(50))/2, SIZE_SCALE(50), SIZE_SCALE(50) ),
    [7] = uiTextScroll( SIZE_SCALE(70), 0, GUI_LCD_RES_H - SIZE_SCALE(70),  ITEM_HEIGHT, COLOR_BLACK, COLOR_WHITE, ALIGN_LEFT_CENTOR, FILL_NONE, ENCODING_UNICODE, FONT_UNICODE_20_29 ),

    // 
    [8] = uiStackTouch( 0, ITEM_HEIGHT * 1, GUI_LCD_RES_H, ITEM_HEIGHT, 2, 2 ),
    [9] = uiDigital( IMG_Exercise_Type_Icon_075_075_14, SIZE_SCALE(14), (ITEM_HEIGHT-SIZE_SCALE(50))/2, SIZE_SCALE(50), SIZE_SCALE(50) ),
    [10] = uiTextScroll( SIZE_SCALE(70), 0, GUI_LCD_RES_H - SIZE_SCALE(70), ITEM_HEIGHT, COLOR_BLACK, COLOR_WHITE, ALIGN_LEFT_CENTOR, FILL_NONE, ENCODING_UNICODE, FONT_UNICODE_20_29 ),

    // 
    [11] = uiStackTouch( 0, ITEM_HEIGHT * 2, GUI_LCD_RES_H, ITEM_HEIGHT, 2, 3 ),
    [12] = uiDigital( IMG_Exercise_Type_Icon_075_075_14, SIZE_SCALE(14), (ITEM_HEIGHT-SIZE_SCALE(50))/2, SIZE_SCALE(50), SIZE_SCALE(50) ),
    [13] = uiTextScroll( SIZE_SCALE(70), 0, GUI_LCD_RES_H - SIZE_SCALE(70), ITEM_HEIGHT, COLOR_BLACK, COLOR_WHITE, ALIGN_LEFT_CENTOR, FILL_NONE, ENCODING_UNICODE, FONT_UNICODE_20_29 ),

    // // 
    [14] = uiStackTouch( 0, ITEM_HEIGHT * 3, GUI_LCD_RES_H, ITEM_HEIGHT, 2, 4 ),
    [15] = uiDigital( IMG_Exercise_Type_Icon_075_075_14, SIZE_SCALE(14), (ITEM_HEIGHT-SIZE_SCALE(50))/2, SIZE_SCALE(50), SIZE_SCALE(50) ),
    [16] = uiTextScroll( SIZE_SCALE(70), 0, GUI_LCD_RES_H - SIZE_SCALE(70), ITEM_HEIGHT, COLOR_BLACK, COLOR_WHITE, ALIGN_LEFT_CENTOR, FILL_NONE, ENCODING_UNICODE, FONT_UNICODE_20_29 ),

    // // 
    [17] = uiStackTouch( 0, ITEM_HEIGHT * 4, GUI_LCD_RES_H, ITEM_HEIGHT, 2, 5 ),
    [18] = uiDigital( IMG_Exercise_Type_Icon_075_075_14, SIZE_SCALE(14), (ITEM_HEIGHT-SIZE_SCALE(50))/2, SIZE_SCALE(50), SIZE_SCALE(50) ),
    [19] = uiTextScroll( SIZE_SCALE(70), 0, GUI_LCD_RES_H - SIZE_SCALE(70), ITEM_HEIGHT, COLOR_BLACK, COLOR_WHITE, ALIGN_LEFT_CENTOR, FILL_NONE, ENCODING_UNICODE, FONT_UNICODE_20_29 ),
};

GUI_VIEW_DEF( viewExercise_Selection ) = 
{
    // name 
    .name = "Exercise+Select",
    
    // init 
    .init = initialize,
    .display_func = display_callback_func,
    .refresh_func_check = display_refresh_func,
    .destroy_func = on_destroy_func,
    .set_parent_func = on_set_parent_func, 
    
    // input 
    .on_touch = on_touch,
    .on_button = on_button,
    .on_event_update = on_event_update,     
    
    .pWidgetlist =  (ui_widgets_type_t*)wglExerciseSelection /* 3. fill with widgets list name */,
    .widget_cnt = WIDGET_COUNT( wglExerciseSelection ), /* 3. fill with widgets list name */

    .flag = GUI_VIEW_FLAG_FUNC
};

static gui_fling_t*     mp_exercise_fling = NULL;
static int16_t          m_idx_of_first_item = -1;
static int16_t          roll_total_last = 0;

/* 当前view初始化
// 需要指定前使用的控件组
// 自动更新间隔，不使用自动更新间隔则interval = 0

*/
static void initialize(gui_menu_t * menu, void* pvParameter)
{
    menu->interval = 1000;
    menu->lifetime = VIEWS_LIFETIME_DEFAULT; 

    mp_exercise_fling = gui_fling_get();
    gui_fling_init_t init_obj = GUI_FLING_CONFIG( 0, 0, GUI_LCD_RES_H, GUI_LCD_RES_V, true, ROLL_V_MIN_OFFSET, ROLL_V_MAX_OFFSET, ITEM_HEIGHT, 100, NULL );
    gui_fling_init( mp_exercise_fling, &init_obj );

    gui_group_scroll_reset();
    gui_share_refresh_part_reset();
}
static void on_set_parent_func(gui_menu_t * menu, const gui_view_t * parent)
{
   p_this_parent = parent;
}
/* 销毁函数
// 在销毁前处理当前信息，比如不允许销毁时，将当前界面状态保存为background。
// true:  允许销毁
// false: 不允许自动销毁，则GUI只关闭当前显示，输入事件仍由当前view进行处理。
          那么view判断当前状态为background时，作出对应background下的按键、触摸等事件反馈
*/
static uint32_t on_destroy_func(gui_menu_t * menu)
{
    roll_total_last = mp_exercise_fling->roll_offset_total;

    gui_fling_set_disable( mp_exercise_fling );    
    return GUI_DESTROY_RET_DEFAULT; 
}

/* 显示回调
   重新指定参数, 用来获取当前界面的控件组
   ** 当前界面有多个控件组时，应该有条件确定使用哪一组控件组 ** 
*/
static void display_callback_func(gui_menu_t * menu)
{
    ui_property_t prop;
    ui_widgets_type_t * widgets = menu->widgets;
    bool draw = false;
    
    widgets[1].visible = 0;

    if( IS_REQ_SRC_CREATE( menu->source ) )
    {
        draw = true; 
        // 由子界面 返回
        if( menu->source == GUI_VIEW_REQ_SRC_CREATE_RETURN )
        {
            mp_exercise_fling->roll_offset_total = roll_total_last; // 使用上次的偏移量
        } 

        if( IS_REQ_SRC_CREATE_SINGLE( menu->source )) // == GUI_VIEW_REQ_SRC_CREATE || menu->source == GUI_VIEW_REQ_SRC_CREATE_RETURN )
        {
//            gui_part_t part = GUI_PART_CONFIG_ALL( gui_share_refresh_part_get(), ItemCount, 500 );
//            gui_part_create( &part );
        }
    }
    else // 保存偏移量
    {
        ui_widgets_type_t* p = &widgets[4];
        for(int16_t i = 0; i < ItemCount; i ++)
        {            
            gui_group_scroll_set( i, m_idx_of_first_item + i, p->uiTextScroll.extension->textscroll.delta_x);
            p += 3; 
        }
        if( menu->source == GUI_VIEW_REQ_SRC_UPDATE_FLING )
        {
            draw = true;
        }
    }

    if( draw )
    {
        // 计算滚动偏移位置 对应的 item序号
        m_idx_of_first_item = -((mp_exercise_fling->roll_offset_total / ITEM_HEIGHT) + 1);
        // 更新偏移量
        gui_layout_update_general_container_calc( widgets, WIDGET_COUNT( wglExerciseSelection), mp_exercise_fling->item_delta, UI_WIDGET_TYPE_STACK );

        // 更新文字刷新的位置 
        int16_t i;
//        ui_widgets_type_t* pw = &widgets[2];
//        for( i = 0; i < ItemCount; i ++)
//        {
//            int16_t x = pw->x + pw->uiStack.delta_x + SIZE_SCALE(70);
//            int16_t y = pw->y + pw->uiStack.delta_y + 0;
//            gui_share_refresh_part_set( i, x, y, GUI_LCD_RES_H - SIZE_SCALE(70), ITEM_HEIGHT );
//            pw += 3;
//        }

        string_t const *s;
        int16_t index = m_idx_of_first_item;
        int16_t idx_of_container = 2;
        ui_widgets_type_t* p_textscroll;
        for( i = 0; i < ItemCount; i ++)
        {
            if( index < 0 || index >= IDX_MAXIMUM )
            {
                widgets[idx_of_container].visible = 0;
                index ++;
                idx_of_container += 3;
                continue;
            }
            
            widgets[idx_of_container].visible = 1;

            // icon
            PROP_ASSIGN_DIGITAL( prop, item_list[index].idx );
            gui_widget_update_prop( widgets + idx_of_container + 1, &prop );

            s = xapp_local_text_item_get( (int) item_list[index].text );
            if( s != NULL )
            {
                PROP_ASSIGN_TEXTSCROLL_STRING( prop, s );
                gui_widget_update_prop( widgets + idx_of_container + 2, &prop );

                p_textscroll = &widgets[ idx_of_container + 2];
                p_textscroll->uiTextScroll.extension->textscroll.nx = p_textscroll->x + gui_group_scroll_get(index);
            }

            index ++;
            idx_of_container += 3;
        }
    }

    // 局部更新请求, 更新滚动文字偏移量
//    if( menu->source == GUI_VIEW_REQ_SRC_UPDATE_PART )
//    {
//        // 更新 滚动文字坐标
//        int index = 4;
//        for(int i = 0; i < ItemCount; i ++ )
//        {
//            prop.textscrolled.content = NULL;
//            prop.textscrolled.len = 0;
//            prop.textscrolled.roll_delta_x = -1; 
//            gui_widget_update_prop( &widgets[index], &prop );
//            index += 3; 
//        }
//    }
}

/* 刷新显示回调
   根据当前状态，重新绘制指定的控件组 
*/
static int display_refresh_func(gui_menu_t * menu)
{
    return 1;
}

static void on_touch(void* pvParameters, gui_menu_t * menu)
{
    tp_algo_evt_t* touch = (tp_algo_evt_t*)pvParameters;
    gui_core_lifetime_refresh(menu);
    switch( touch->type )
    {
        case TP_ALGO_EVT_TYPE_DOWN:
        gui_fling_on_touch_press( mp_exercise_fling );
        break;

        case TP_ALGO_EVT_TYPE_UP:
        gui_fling_on_touch_release( mp_exercise_fling );
        break;

        case TP_ALGO_EVT_TYPE_CLICK:        
        GUI_WIDGET_LIST_CHECK_TOUCH( menu->widgets, WIDGET_COUNT(wglExerciseSelection), 0, 0, touch->x, touch->y, list_item_handler );
        break;

        case TP_ALGO_EVT_TYPE_HOLD:
        if( touch->deltaY != 0 )
        {
            gui_fling_set_roll( mp_exercise_fling, touch->deltaY );
        }
        break;

        
        case TP_ALGO_EVT_TYPE_SLIDE_D:
        gui_fling_switch_item( mp_exercise_fling, 2, false );
        break;
        
        case TP_ALGO_EVT_TYPE_SLIDE_U:
        gui_fling_switch_item( mp_exercise_fling, 2, true );
        break;
        
        case TP_ALGO_EVT_TYPE_SLIDE_R:
        local_view_event_handler( tagExerciseSelectReturn ); 
        break;
        
        default:
        break;
    }
}
/* 界面的按键处理

*/
static void on_button(void* pvParameters, gui_menu_t * menu)
{
    kb_evt_t * kb = (kb_evt_t*)pvParameters;
    
    switch( kb->type ) 
    {
        case KB_EVT_CLICK:
        local_view_event_handler( tagExerciseSelectReturn );
        break; 
           
        case KB_EVT_SHORT_HOLD_READY:

        break;

        default:
            break;
    }
 
}

/* 界面的自定义输入事件处理

*/
static void on_event_update(void * pvParameters, gui_menu_t * menu)
{
    custom_evt_t* custom = (custom_evt_t*)pvParameters;
    switch( custom->type )
    {
        case CUSTOM_EVT_TYPE_RAISE_WRIST:
        break;

        case CUSTOM_EVT_TYPE_DROP_WRIST:
        break;
        
        default:
        break;
    }
}

static void list_item_handler(uint32_t tag)
{
    int idx = (int)(tag + m_idx_of_first_item);
    if( idx < 0 || idx >= IDX_MAXIMUM )
    {
        return;
    }
    uint32_t itemtag = item_list[idx].type;
    local_view_event_handler( itemtag );
}

/* 界面的触摸事件
   tag 是生效的控件id, 用户根据生效的tag判断是哪个控件点击了，进行处理
*/
static void local_view_event_handler( uint32_t tag )
{
    switch( tag )
    {
        case tagExerciseSelectItemRunning:
        case tagExerciseSelectItemWalking:
        case tagExerciseSelectItemRiding:
        case tagExerciseSelectItemClimbing:
        case tagExerciseSelectItemSwimming:
        case tagExerciseSelectItemRopeskipping:
        case tagExerciseSelectItemHula:
        case tagExerciseSelectItemBasketball:
        case tagExerciseSelectItemVolleyball:
        case tagExerciseSelectItemBadmiton:
        case tagExerciseSelectItemFootball:
        {
            xapp_exercise_set( (xapp_exercise_type_t) item_list[tag].type );
            gui_view_create( &viewExercise_Counting );
        }
        break;;


        case tagExerciseSelectReturn:
        {
            if( p_this_parent != NULL )
            {
                gui_view_create_return( p_this_parent );
            }
            else 
            {
                gui_view_create_return( &viewAppsList ); // 返回功能列表
            }
        }
        break;;
    }
}
